package awk.script.javassist.field02;
//import javassist.*;

import javassist.*;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * @author yujianlong
 * @create 2021-03-19 23:47
 **/
public class AddConstructor {
	public static void main(String[] args) throws NotFoundException, CannotCompileException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
		ClassPool classPool = ClassPool.getDefault();

		classPool.importPackage("java.util.List");
		classPool.importPackage("java.util.ArrayList");

		//创建类 用makeClass
		CtClass ctClass = classPool.makeClass("com.yu.test.javassist.create01.testClass04");

		//添加属性
		ctClass.addField(CtField.make("private int para = 5;", ctClass));
		ctClass.addField(CtField.make("private List/*<String>*/ containers = new ArrayList/*<>*/();", ctClass));

		//添加setPara方法
		ctClass.addMethod(CtMethod.make("public void setPara(int para){this.para = para;}", ctClass));
		ctClass.addMethod(CtMethod.make("public int getPara(){ return this.para;}", ctClass));
		ctClass.addMethod(CtMethod.make("public List/*<String>*/ getContainers() {return containers;}", ctClass));
		ctClass.addMethod(CtMethod.make("public void setContainers(List/*<String>*/ containers) {this.containers = containers;}", ctClass));
		ctClass.addMethod(CtMethod.make("public static void main(String[] args) {\n" +
				"\t\tSystem.out.println(\"hello,xdf,this my test04\");\n" +
				"\t\tSystem.out.println(\"你好世界\");\n" +
				"\t}", ctClass));

		// 创建无参数构造方法
		CtConstructor ctConstructor = new CtConstructor(new CtClass[]{}, ctClass);
		ctConstructor.setBody("{}");
		ctClass.addConstructor(ctConstructor);

		//创建全参构造
		// CtClass.intType, classPool.get("java.sql.Connection" classPool.get("java.lang.String") CtClass.intType
		CtClass[] contructorParameters=new  CtClass[]{CtClass.intType,classPool.get("java.util.List")};
		CtConstructor ctConstructorAllArgs = new CtConstructor(contructorParameters, ctClass);
		ctConstructorAllArgs.setBody("{\n" +
				"\t\t$0.para = $1;\n" +
				"\t\t$0.containers = $2;\n" +
				"\t}");

		ctClass.addConstructor(ctConstructorAllArgs);


		//或者生成到指定目录
		//将ctClass生成字节数组，并写入文件
//		byte[] byteArray = ctClass.toBytecode();
//		String writeFilePath = "/Users/yujianlong/Movies/test3/testClass04.class";
//
//		FileUtil.writeBytes(byteArray,writeFilePath);


		ctClass.writeFile("/Users/yujianlong/Movies/test3/testClass05");


		// 测试调用
		Class clazz = ctClass.toClass();
		Method main = clazz.getDeclaredMethod("main", String[].class);
		main.invoke(null, (Object)new String[1]);

		Constructor constructor = clazz.getConstructor(int.class, java.util.List.class);
		Object o = constructor.newInstance(9, new ArrayList<String>());
		Method getParaMethod = clazz.getDeclaredMethod("getPara");
		Object invoke = getParaMethod.invoke(o);
		System.out.println(invoke);


	}

}
